﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Animation;
using System.Windows.Threading;

using Matchingo.Common.Types.Interfaces;
using Matchingo.Common.Types.Types;

namespace Matchingo.UserControls.PlainCardControl
{
    public partial class PlainCardUserControl : UserControl, ICardUserControl
    {
        private static readonly Random RandomGenerator = new Random();

        #region ========== Private Properties ==========

        private Image FrontImage { get; set; }
        private Card.CardSide VisibleSide { get; set; }

        #endregion

        #region ========== Public Properties ==========

        public Card Card { get; set; }

        #endregion

        #region ========== Constructors ==========

        public PlainCardUserControl()
		{
			// Required to initialize variables
			InitializeComponent();
        }

        public PlainCardUserControl(Card c, Image frontImage)
        {
            // Required to initialize variables
            InitializeComponent();

            Card = c;
            c.CardFlippedEvent += CardFlippedEvent;

            FrontImage = frontImage;

            VisibleSide = Card.CardSide.Rear;
        }

        #endregion

        #region ========== Public Methods ==========
        
        public void Initialize()
        {
            FrontImageImage.Source = FrontImage.Source;
            // RearImageImage.Source = RearImage.Source;

            Card.CardMatchedEvent += CardMatchedEvent;
            this.MouseEnter += PlainCardUserControlMouseEnter;
            this.MouseLeave += PlainCardUserControlMouseLeave;
        }

        public void PlayDealingAnimation()
        {
            // this control has 4 dealing animations, show them at random
            Storyboard sbShowFront;

            int animationIndex = RandomGenerator.Next(0, 4);
            switch (animationIndex)
            {
                case 0:
                    sbShowFront = (Storyboard)this.Resources["CardDealingTop"];
                    break;
                case 1:
                    sbShowFront = (Storyboard)this.Resources["CardDealingBottom"];
                    break;
                case 2:
                    sbShowFront = (Storyboard)this.Resources["CardDealingLeft"];
                    break;
                case 3:
                    sbShowFront = (Storyboard)this.Resources["CardDealingRight"];
                    break;
                default:
                    throw new ArgumentException("PlainCardUserControl.PlayDealingAnimation() did not get an animation to play");
            }

            sbShowFront.Begin();
        }
       
        #endregion

        #region ========== Event Handlers ==========

        private void CardFlippedEvent(object sender, PropertyChangedEventArgs e)
        {
            // we only want to fire animations if it has changed
            if (Card.VisibleSide == VisibleSide)
                return;

            // ShowFront, ShowBack, HideFront, HideBack

            if (Card.VisibleSide == Card.CardSide.Front)
            {
                Storyboard sbHideBack = (Storyboard)this.Resources["HideBack"];
                sbHideBack.Completed += (s, e2) =>
                {
                    Storyboard sbShowFront = (Storyboard)this.Resources["ShowFront"];
                    sbShowFront.Begin();

                    VisibleSide = Card.CardSide.Front;
                };
                sbHideBack.Begin();
            }
            else if (Card.VisibleSide == Card.CardSide.Rear)
            {
                Storyboard sbHideFront = (Storyboard)this.Resources["HideFront"];
                sbHideFront.Completed += (s, e2) =>
                {
                    Storyboard sbShowBack = (Storyboard)this.Resources["ShowBack"];
                    sbShowBack.Begin();

                    VisibleSide = Card.CardSide.Rear;
                };
                sbHideFront.Begin();
            }
        }

        void CardMatchedEvent(object sender, PropertyChangedEventArgs e)
        {
            // HACK:: this delay is duplicated in CardGridModule.FireParticleAnimationBehindCard
            // TODO:: need to review all of these times and make sure they disconnect
            DispatcherTimer dt = new DispatcherTimer();
            dt.Interval = new TimeSpan(0, 0, 0, 0, 500); // 500 Milliseconds
            dt.Tick += (s, e2) =>
                {
                    Storyboard sbShowFront = (Storyboard)this.Resources["ExplodeMatch"];
                    sbShowFront.Begin();
                    dt.Stop();
                };
            dt.Start();
        }

        void PlainCardUserControlMouseLeave(object sender, MouseEventArgs e)
        {
            VisualStateManager.GoToState(this, "MouseOut", true);
        }

        void PlainCardUserControlMouseEnter(object sender, MouseEventArgs e)
        {
            VisualStateManager.GoToState(this, "MouseOver", true);
        }

        #endregion
    }
}